package com.googlecode.stockhamster.client.console;

import java.io.IOException;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.util.List;

import com.googlecode.stockhamster.Constant;
import com.googlecode.stockhamster.arbiter.IArbiter;
import com.googlecode.stockhamster.bank.IBank;
import com.googlecode.stockhamster.company.ICompany;
import com.googlecode.stockhamster.rumor.IRumor;
import com.googlecode.stockhamster.stockmarket.IStockMarket;
import com.googlecode.stockhamster.stockstat.IStockStat;
import com.googlecode.stockhamster.utils.XFireStub;

public class ConsoleClient {

	public static void main(String[] args) throws MalformedURLException {
		IBank bank = new XFireStub<IBank>(Constant.bankUrl, IBank.class)
				.getStub();
		IStockMarket stockmarket = new XFireStub<IStockMarket>(
				Constant.stockMarketUrl, IStockMarket.class).getStub();
		IStockStat status = new XFireStub<IStockStat>(Constant.stockStatUrl,
				IStockStat.class).getStub();
		IArbiter arbiter = new XFireStub<IArbiter>(Constant.arbiterUrl,
				IArbiter.class).getStub();
		IRumor rumor = new XFireStub<IRumor>(Constant.rumorUrl,
				IRumor.class).getStub();
		ICompany company = new XFireStub<ICompany>(Constant.companyUrl,
				ICompany.class).getStub();

		LineNumberReader in = new LineNumberReader(new InputStreamReader(
				System.in));
		String line;
		try {
			while (true) {
				line = in.readLine();
				if (line == null)
					break;
				String[] pieces = line.split(" ");
				if (pieces[0].equals("arbiter"))
					invoke(arbiter, pieces);
				else if (pieces[0].equals("status"))
					invoke(status, pieces);
				else if (pieces[0].equals("bank"))
					invoke(bank, pieces);
				else if (pieces[0].equals("stockmarket"))
					invoke(stockmarket, pieces);
				else if (pieces[0].equals("rumor"))
					invoke(rumor, pieces);
				else if (pieces[0].equals("company"))
					invoke(company, pieces);
				else
					System.out.println("unknow command");
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	private static void invoke(Object stub, String[] pieces) {
		for (Method m : stub.getClass().getMethods()) {
			if (!m.getName().equals(pieces[1]))
				continue;
			if (!(m.getParameterTypes().length == pieces.length - 2))
				continue;
			Class<?>[] paramTypes = m.getParameterTypes();
			Object[] params = new Object[m.getParameterTypes().length];
			try {
				for (int i = 2; i < pieces.length; i++)
					params[i - 2] = paramTypes[i - 2].getConstructor(
							String.class).newInstance(pieces[i]);
			} catch (Exception e) {
				e.printStackTrace();				
				continue;
			}
			try {
				Object res = m.invoke(stub, params);
				if (res instanceof List)
					for (Object o : (List<?>) res)
						System.out.println(o);
				else
					System.out.println(res);
			} catch (Exception e) {
				e.printStackTrace();
			}
			return;
		}
		System.out.println("unknow command inside");
	}
}
